home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / emula / arosdv19.lha / AROS / devs / timer.c < prev    next >
C/C++ Source or Header  |  1996-10-24  |  5KB  |  228 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id$
  4.  
  5.     Desc: Timer.device
  6.     Lang: english
  7. */
  8. #define timeval     linux_timeval
  9. #include <sys/time.h>
  10. #undef timeval
  11. #include <devices/timer.h>
  12. #include <clib/exec_protos.h>
  13. #include <aros/libcall.h>
  14. #ifdef __GNUC__
  15. #   include "nil_handler_gcc.h"
  16. #endif
  17.  
  18. static const char name[];
  19. static const char version[];
  20. static const APTR inittabl[4];
  21. static void *const functable[];
  22. struct nilbase *AROS_SLIB_ENTRY(init,timer)();
  23. void AROS_SLIB_ENTRY(open,timer)();
  24. BPTR AROS_SLIB_ENTRY(close,timer)();
  25. BPTR AROS_SLIB_ENTRY(expunge,timer)();
  26. int AROS_SLIB_ENTRY(null,timer)();
  27. void AROS_SLIB_ENTRY(beginio,timer)();
  28. LONG AROS_SLIB_ENTRY(abortio,timer)();
  29. static const char end;
  30. static void NextTick (ULONG usec);
  31. static void timer (int dummy);
  32.  
  33. int timer_entry(void)
  34. {
  35.     /* If the handler was executed by accident return error code. */
  36.     return -1;
  37. }
  38.  
  39. const struct Resident timer_resident=
  40. {
  41.     RTC_MATCHWORD,
  42.     (struct Resident *)&timer_resident,
  43.     (APTR)&end,
  44.     RTF_AUTOINIT,
  45.     1,
  46.     NT_DEVICE,
  47.     0,
  48.     (char *)name,
  49.     (char *)&version[6],
  50.     (ULONG *)inittabl
  51. };
  52.  
  53. static const char name[]=TIMERNAME;
  54.  
  55. static const char version[]="$VER: " TIMERNAME " 1.0 (17.10.96)\n\015";
  56.  
  57. static const APTR inittabl[4]=
  58. {
  59.     (APTR)sizeof(struct timerbase),
  60.     (APTR)functable,
  61.     NULL,
  62.     &AROS_SLIB_ENTRY(init,timer)
  63. };
  64.  
  65. static void *const functable[]=
  66. {
  67.     &AROS_SLIB_ENTRY(open,timer),
  68.     &AROS_SLIB_ENTRY(close,timer),
  69.     &AROS_SLIB_ENTRY(expunge,timer),
  70.     &AROS_SLIB_ENTRY(null,timer),
  71.     &AROS_SLIB_ENTRY(beginio,timer),
  72.     &AROS_SLIB_ENTRY(abortio,timer),
  73.     (void *)-1
  74. };
  75.  
  76. AROS_LH2(struct timerbase *, init,
  77.  AROS_LHA(struct timerbase *, timerbase, D0),
  78.  AROS_LHA(BPTR,             segList, A0),
  79.        struct ExecBase *, sysBase, 0, timer)
  80. {
  81.     AROS_LIBFUNC_INIT
  82.     struct itimerval interval;
  83.  
  84.     /* Store arguments */
  85.     timerbase->sysbase=sysBase;
  86.     timerbase->seglist=segList;
  87.  
  88.     /* Start timer */
  89.     signal (SIGALRM, timer);
  90.  
  91.     interval.it_interval.tv_sec = interval.it_value.tv_sec = 0;
  92.     interval.it_interval.tv_usec = interval.it_value.tv_usec = 1000000/50;
  93.  
  94.     setitimer (ITIMER_REAL, &interval, NULL);
  95.  
  96.     return NULL;
  97.     AROS_LIBFUNC_EXIT
  98. }
  99.  
  100. AROS_LH3(void, open,
  101.  AROS_LHA(struct IOFileSys *, iofs, A1),
  102.  AROS_LHA(ULONG,              unitnum, D0),
  103.  AROS_LHA(ULONG,              flags, D0),
  104.        struct timerbase *, timerbase, 1, timer)
  105. {
  106.     AROS_LIBFUNC_INIT
  107.     struct TimeRequest *unit;
  108.  
  109.     /* Get compiler happy */
  110.     unitnum=flags=0;
  111.  
  112.     /* I have one more opener. */
  113.     timerbase->device.dd_Library.lib_OpenCnt++;
  114.  
  115.     /* Mark Message as recently used. */
  116.     iofs->IOFS.io_Message.mn_Node.ln_Type=NT_REPLYMSG;
  117.  
  118.     unit=AllocMem(sizeof(struct TimeRequest),MEMF_PUBLIC|MEMF_CLEAR);
  119.     if(dev!=NULL)
  120.     {
  121.     iofs->IOFS.io_Unit=(struct Unit *)unit;
  122.     iofs->IOFS.io_Device=&timerbase->device;
  123.     timerbase->device.dd_Library.lib_Flags&=~LIBF_DELEXP;
  124.     iofs->IOFS.io_Error=0;
  125.     return;
  126.     }else
  127.     iofs->io_DosError=ERROR_NO_FREE_STORE;
  128.  
  129.     iofs->IOFS.io_Error=IOERR_OPENFAIL;
  130.     timerbase->device.dd_Library.lib_OpenCnt--;
  131.  
  132.     AROS_LIBFUNC_EXIT
  133. }
  134.  
  135. AROS_LH1(BPTR, close,
  136.  AROS_LHA(struct IOFileSys *, iofs, A1),
  137.        struct timerbase *, timerbase, 2, timer)
  138. {
  139.     AROS_LIBFUNC_INIT
  140.     struct TimeRequest *unit;
  141.  
  142.     unit=(struct TimeRequest *)iofs->IOFS.io_Unit;
  143.     if(unit->count)
  144.     {
  145.     iofs->io_DosError=ERROR_OBJECT_IN_USE;
  146.     return 0;
  147.     }
  148.  
  149.     /* Let any following attemps to use the device crash hard. */
  150.     iofs->IOFS.io_Device=(struct Device *)-1;
  151.     FreeMem(unit,sizeof(struct TimeRequest));
  152.     iofs->io_DosError=0;
  153.  
  154.     /* I have one fewer opener. */
  155.     timerbase->device.dd_Library.lib_OpenCnt --;
  156.  
  157.     return 0;
  158.     AROS_LIBFUNC_EXIT
  159. }
  160.  
  161. AROS_LH0(BPTR, expunge, struct timerbase *, timerbase, 3, timer)
  162. {
  163.     AROS_LIBFUNC_INIT
  164.     return 0; /* Never allow to expunge */
  165.     AROS_LIBFUNC_EXIT
  166. }
  167.  
  168. AROS_LH0I(int, null, struct timerbase *, timerbase, 4, timer)
  169. {
  170.     AROS_LIBFUNC_INIT
  171.     return 0;
  172.     AROS_LIBFUNC_EXIT
  173. }
  174.  
  175. AROS_LH1(void, beginio,
  176.  AROS_LHA(struct timerequest *, tr, A1),
  177.        struct timerbase *, timerbase, 5, timer)
  178. {
  179.     AROS_LIBFUNC_INIT
  180.     LONG error=0;
  181.  
  182.     /*
  183.     Do everything quick no matter what. This is possible
  184.     because I never need to Wait().
  185.     */
  186.     switch(tr->tr_node.io_Command)
  187.     {
  188.     case TR_ADDREQUEST:
  189.  
  190.     default:
  191.     error=ERROR_NOT_IMPLEMENTED;
  192.     break;
  193.     }
  194.  
  195.     /* Set error code */
  196.     tr->tr_node.io_Error=error;
  197.  
  198.     /* If the quick bit is not set send the message to the port */
  199.     if(!(tr->tr_node.io_Flags&IOF_QUICK))
  200.     ReplyMsg(&tr->tr_node.io_Message);
  201.  
  202.     AROS_LIBFUNC_EXIT
  203. }
  204.  
  205. AROS_LH1(LONG, abortio,
  206.  AROS_LHA(struct IOFileSys *, iofs, A1),
  207.        struct timerbase *, timerbase, 6, timer)
  208. {
  209.     AROS_LIBFUNC_INIT
  210.     /* Everything already done. */
  211.     return 0;
  212.     AROS_LIBFUNC_EXIT
  213. }
  214.  
  215. static void timer (int dummy)
  216. {
  217.     signal (SIGALRM, timer);
  218.  
  219.     if (SysBase->TDNestCnt >= 0
  220.     && SysBase->ThisTask->tc_Node.ln_Pri <=
  221.         ((struct Task *)SysBase->TaskReady.lh_Head)->tc_Node.ln_Pri)
  222.     Switch ();
  223.     else
  224.     SysBase->AttnResched |= 0x80;
  225. }
  226.  
  227. static const char end=0;
  228.